package com.amkai.aes.webservice.binary.objecthandler.prefcards;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;

import com.amkai.aes.aescommon.service.binary.job.prefcards.PrefCardJobResult;
import com.amkai.aes.aescommon.service.binary.job.prefcards.PrefCardLazyResolver;
import com.amkai.aes.aescommon.service.binary.job.prefcards.PreferenceCardJob;
import com.amkai.aes.aescommon.service.binary.job.prefcards.PreferenceCardJobKind;
import com.amkai.aes.aescommon.service.binary.job.prefcards.ThinPreferenceCard;
import com.amkai.aes.aescommon.service.result.dictionary.ItemSkeleton;
import com.amkai.aes.generatedbeans.preferencecard.BuildCarByType;
import com.amkai.aes.generatedbeans.preferencecard.CardType;
import com.amkai.aes.generatedbeans.preferencecard.OpenHoldElement;
import com.amkai.aes.generatedbeans.preferencecard.PreferenceCard;
import com.amkai.aes.generatedbeans.preferencecard.PreferenceCardElement;
import com.amkai.aes.generatedbeans.preferencecard.ReleatedProcedure;
import com.amkai.aes.generatedbeans.preferencecard.SurgeonPreferences;
import com.amkai.aes.generatedbeans.procedure.Procedure;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;

public class PreferenceCardHandler implements JobObjectHandler<PreferenceCardJob,Serializable, PrefCardJobResult> {

	private static final String prefCardsQuery = " SELECT pref FROM PreferenceCard pref WHERE id in (:cardIds) AND pref.businessEntity.id = :businessID";
	
	
	private Procedure readProcedureProperties(Procedure procedure) {
		procedure.getId();
		procedure.getId();
		procedure.getShortName();
		procedure.getName();
		if (procedure.getProcedureType() != null) {
			procedure.getProcedureType().getName();
			procedure.getProcedureType().getKind();
			procedure.getProcedureType().getShortName();
		}
		return procedure;
	}
	@SuppressWarnings("unchecked")
	@Override
	public PrefCardJobResult process(PreferenceCardJob job, Serializable object) throws Exception {
		PrefCardJobResult jobResult = new PrefCardJobResult();
		SessionManager sm = null;
		try {
			// KKORNEL: AES-15040
			if (job.getJobKind() == PreferenceCardJobKind.DOWNLOAD_PREFRENCECARDS) {
				Query query = null;
	
				sm = SiteManager.Start();
				query = sm.execute(prefCardsQuery);
				query = query.setParameterList("cardIds", job.getCardIds());
				query.setLong("businessID", job.getModuleDepartment().getId());
	
				List<PreferenceCard> pl=  query.list();
				for(PreferenceCard p : pl){
				p.getId();
				p.getAnestType();
				p.getBuildCardByType();
				p.getCardName();
				p.getCirculatingNursesCount();
				p.getGroundingPad();
				p.getOrTime();
				p.getPacuTime();
				p.getPatientPosition();
				p.getSafetyStrap();
				p.getScrubNursesCount();
				p.getSkinPreparation();
				p.getStepDownTime();
				p.getSurgeonDetailsComment();
				p.getType();
				// #5947
				Procedure mainProcedure = p.getMainCode();
				if (mainProcedure != null) {
					mainProcedure = readProcedureProperties(mainProcedure);
				}
	
				PrefCardLazyResolver.resolve(p);
				
				if (p.getProvider() != null) {
					p.getProvider().getId();
					p.getProvider().getName();
					if (p.getProvider().getSpecialty() != null) {
						p.getProvider().getSpecialty().getId();
						p.getProvider().getSpecialty().getName();
						p.getProvider().getSpecialty().getShortName();
						p.getProvider().getSpecialty();
					}
	
					p.getProvider().getShortName();
					for (SurgeonPreferences s : p.getProvider().getSurgeonPreferences()) {
						s.getId();
						if (s.getLastRevisited() != null) {
							s.getLastRevisitedBy().getId();
							s.getLastRevisitedBy().getName();
							s.getLastRevisitedBy().getPassword();
						}
						if (s.getPreferedLab() != null) {
							s.getPreferedLab().getId();
						}
					}
					p.getProvider();
	
				}
	
				if (p.getSpecialty() != null) {
					p.getSpecialty().getId();
					p.getSpecialty().getName();
					p.getSpecialty().getShortName();
	
					p.getSpecialty();
				}
	
				for (PreferenceCardElement pe : p.getPreferenceCardElements()) {
					pe.getId();
					if (pe.getTray() != null) {
						pe.getTray().getId();
						pe.getTray().getName();
						pe.getTray().getShortName();
						pe.getTray().getBarCode();
						pe.getTray().getRfidCode();
					}
					if (pe.getResource() != null) {
						pe.getResource().getName();
						if (pe.getResource().getCategory() != null) {
							pe.getResource().getCategory().getName();
						}
					}
	
					for (OpenHoldElement ohe : pe.getOpenHoldElements()) {
						ohe.getId();
					}
				}
	
				for (ReleatedProcedure releatedProcedure : p.getReleatedProcedures()) {
					releatedProcedure.getId();
					// #5947
					Procedure procedure = releatedProcedure.getProcedure();
					procedure = readProcedureProperties(procedure);
				}
	
				if (p.getPassport() != null) {
					p.getPassport().getId();
					p.getPassport().getPassword();
					p.getPassport().getName();
				}
				}
				jobResult.setCards(pl);
			} else if (job.getJobKind() == PreferenceCardJobKind.GET_THIN_PREFRENCECARDLIST) {
				sm = SiteManager.Start();
				List<Object[]> preferenceCardPropertiesList = 
					sm.execute("SELECT pc.id, pc.cardName, pc.orTime, type.name, bcbt.name, prov.id, prov.name, mc.shortName " +
						       "FROM PreferenceCard pc " +
						       "JOIN pc.mainCode mc " +
						       "LEFT JOIN pc.typeWrapper type " +
						       "LEFT JOIN pc.buildCardByTypeWrapper bcbt " +
						       "LEFT JOIN pc.provider prov " +
						       "WHERE (pc.deleted = 0) AND pc.businessEntity.id = :beId)").setLong("beId", job.getModuleDepartment().getId()).list();
				if (preferenceCardPropertiesList != null) {
					List<ThinPreferenceCard> thinCards = new ArrayList<ThinPreferenceCard>();
					for (Object[] preferenceCardProperties : preferenceCardPropertiesList) {
						CardType cardType = (preferenceCardProperties[3] == null) ? null : CardType.valueOf((String) preferenceCardProperties[3]); 
						BuildCarByType buildCardByType = (preferenceCardProperties[4] == null) ? null : BuildCarByType.valueOf((String) preferenceCardProperties[4]);
						ThinPreferenceCard thinPreferenceCard = new ThinPreferenceCard((Long)preferenceCardProperties[0], (String) preferenceCardProperties[1], (Integer)preferenceCardProperties[2], cardType, buildCardByType, (Long) preferenceCardProperties[5], (String) preferenceCardProperties[6], (String) preferenceCardProperties[7]);
						thinCards.add(thinPreferenceCard);						
					}
					jobResult.setThinCards(thinCards);
				}
				
			} else if (job.getJobKind() == PreferenceCardJobKind.GET_THIN_RELATEDPROCEDURES) {
				if (job.getPreferenceCardId() != null) {
					sm = SiteManager.Start();
					List<Object[]> releatedProcedurePropertiesList = 
						sm.execute("SELECT proc.id, proc.active, proc.name, proc.shortName " +
								   "FROM ReleatedProcedure rp " +
								   "JOIN rp.procedure proc " +
								   "WHERE rp.preferenceCard.id = :pcId " +
								   "ORDER BY rp.sequence")
						 .setLong("pcId", job.getPreferenceCardId()).list();
					if (releatedProcedurePropertiesList != null) {
						List<ItemSkeleton> thinReleatedProcedures = new ArrayList<ItemSkeleton>();
						for (Object[] releatedProcedureProperties : releatedProcedurePropertiesList) {
							ItemSkeleton itemSkeleton = new ItemSkeleton((Long)releatedProcedureProperties[0], (Boolean)releatedProcedureProperties[1], (String)releatedProcedureProperties[2], (String)releatedProcedureProperties[3]);
							thinReleatedProcedures.add(itemSkeleton);
						}
						jobResult.setThinReleatedProcedures(thinReleatedProcedures);
					}
				}
			}
		} finally {
			if (sm != null) {
				sm.closeSession();
			}
		}
		return jobResult;
	}

}
